
//% color="#ff9f06" iconWidth=50 iconHeight=40
namespace xunfeiyuyin {

    //% block="xunfei set APPID:[ID] APISecret:[SEC] APIKey:[KEY]" blockType="command"
    //% ID.shadow="string" ID.defl=" " 
    //% SEC.shadow="string" SEC.defl=" " 
    //% KEY.shadow="string" KEY.defl=" " 
    export function xunfeiSet(parameter: any, block: any) {
        let id = parameter.ID.code;
        let sec = parameter.SEC.code;
        let key = parameter.KEY.code;
        
        Generator.addCode(`xunfeiasr_set(APPID=${id},APISecret=${sec},APIKey=${key})`);
        Generator.addDeclaration("xunfeiclass",`
import websocket
import datetime
import hashlib
import base64
import hmac
import json
from urllib.parse import urlencode
import time
import ssl
from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
import _thread as thread
xf_APPID=''
xf_APISecret=''
xf_APIKey=''
wsParam=None
asr_result='' 
STATUS_FIRST_FRAME = 0  
STATUS_CONTINUE_FRAME = 1  
STATUS_LAST_FRAME = 2  
class Ws_Param(object):
    def __init__(self, APPID, APIKey, APISecret, AudioFile):
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.AudioFile = AudioFile
        self.CommonArgs = {"app_id": self.APPID}
        self.BusinessArgs = {"domain": "iat", "language": "zh_cn","ptt":0, "accent": "mandarin", "vinfo":1,"vad_eos":10000}
    def create_url(self):
        url = 'wss://ws-api.xfyun.cn/v2/iat'
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))
        signature_origin = "host: " + "ws-api.xfyun.cn" + "\\n"
        signature_origin += "date: " + date + "\\n"
        signature_origin += "GET " + "/v2/iat " + "HTTP/1.1"
        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                    digestmod=hashlib.sha256).digest()
        signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
        authorization_origin = "api_key=\\"%s\\", algorithm=\\"%s\\", headers=\\"%s\\", signature=\\"%s\\"" % (
            self.APIKey, "hmac-sha256", "host date request-line", signature_sha)
        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
        v = {
            "authorization": authorization,
            "date": date,
            "host": "ws-api.xfyun.cn"
        }
        url = url + '?' + urlencode(v)
        return url
def on_message(ws, message):
    global asr_result
    try:
        code = json.loads(message)["code"]
        sid = json.loads(message)["sid"]
        if code != 0:
            errMsg = json.loads(message)["message"]
            print("sid:%s call error:%s code is:%s" % (sid, errMsg, code))
        else:
            data = json.loads(message)["data"]["result"]["ws"]
            for i in data:
                for w in i["cw"]:
                    asr_result+= w["w"]
    except Exception as e:
        print("receive msg,but parse exception:", e)
def on_error(ws, error):
    print("### error:", error)
def on_close(ws,code,msg):
    pass
def on_open(ws):
    global asr_result
    asr_result=''
    def run(*args):
        frameSize = 8000  
        intervel = 0.04  
        status = STATUS_FIRST_FRAME
        with open(wsParam.AudioFile, "rb") as fp:
            while True:
                buf = fp.read(frameSize)
                if not buf:
                    status = STATUS_LAST_FRAME
                if status == STATUS_FIRST_FRAME:
                    d = {"common": wsParam.CommonArgs,
                            "business": wsParam.BusinessArgs,
                            "data": {"status": 0, "format": "audio/L16;rate=16000",
                                    "audio": str(base64.b64encode(buf), 'utf-8'),
                                    "encoding": "raw"}}
                    d = json.dumps(d)
                    ws.send(d)
                    status = STATUS_CONTINUE_FRAME
                elif status == STATUS_CONTINUE_FRAME:
                    d = {"data": {"status": 1, "format": "audio/L16;rate=16000",
                                    "audio": str(base64.b64encode(buf), 'utf-8'),
                                    "encoding": "raw"}}
                    ws.send(json.dumps(d))
                elif status == STATUS_LAST_FRAME:
                    d = {"data": {"status": 2, "format": "audio/L16;rate=16000",
                                    "audio": str(base64.b64encode(buf), 'utf-8'),
                                    "encoding": "raw"}}
                    ws.send(json.dumps(d))
                    time.sleep(1)
                    break
                time.sleep(intervel)
        ws.close()
    thread.start_new_thread(run, ())
def xunfeiasr_set(APPID,APISecret,APIKey):
    global xf_APPID,xf_APISecret,xf_APIKey
    xf_APPID = APPID
    xf_APISecret =APISecret
    xf_APIKey=APIKey
def xunfeiasr(src):
    global wsParam,xf_APPID,xf_APISecret,xf_APIKey
    wsParam = Ws_Param(APPID=xf_APPID, APISecret=xf_APISecret,
                        APIKey=xf_APIKey,
                        AudioFile=src)
    websocket.enableTrace(False)
    wsUrl = wsParam.create_url()
    ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close)
    ws.on_open = on_open
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
    return asr_result
`)
    }
    //% block="xunfei asr src [SRC]" blockType="reporter"
    //% SRC.shadow="string" SRC.defl="record.wav" 
    export function asr(parameter: any, block: any) {
        let src = parameter.SRC.code;
        Generator.addCode(`xunfeiasr(r${src})`);
 
    }

}
